package com.lyeducation.util.Socket.pointSend;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class PointSendServer {
  private static byte[] ByteMD5(byte[] data) {
    try {
      MessageDigest md = MessageDigest.getInstance("MD5");
      md.update(data);
      return md.digest();
    } catch (NoSuchAlgorithmException e) {
      return new byte[0];
    }
  }

  public static void main(String[] args) {
    new PointSendServer().sendFile();
  }

  public void sendFile() {
    int port = 8821;
    try {
      ServerSocket server = new ServerSocket(port);

      Socket handle = server.accept();
      OutputStream out = handle.getOutputStream();
      InputStream in = handle.getInputStream();
      final int orderLen = 1024;
      byte[] orderArr = new byte[orderLen];
      while (true) {
        // 接收并解析指令
        // 等待client发送指令
        int realOrderLen = in.read(orderArr, 0, orderLen);
        if (realOrderLen < 0) {
          break;
        }
        String orderStr = new String(orderArr, 0, realOrderLen);
        // 解析指令
        String[] order = orderStr.trim().split("\\|"); // 这里是正则表达式，两斜线和一个竖线之间没有空格
        final String filePath = order[0];
        final int piece = Integer.parseInt(order[1]);
        final int pieceSize = Integer.parseInt(order[2]);

        // 通过指令读取指定文件中的指定块
        byte[] buf = new byte[pieceSize]; // 缓冲区
        FileInputStream f = new FileInputStream(filePath);
        //				 这里应该是跳转的位置应该是加而不是乘 piece指定位置 pieceSize从指定位置开始读，需要读取多少
        f.skip(piece * (long) pieceSize); // 跳转
        int realBufLen = f.read(buf); // 读取
        f.close();
        // 数据附上有效数据长度和MD5值
        // 获取md5值并将len转换成byte[]以通过socket传输
        byte[] md5 = ByteMD5(buf);
        byte[] lenInB = ByteBuffer.allocate(4).putInt(realBufLen).array();

        // 合并，有效数据长度、数据的md5值、数据
        ByteBuffer byteBuffer = ByteBuffer.allocate(lenInB.length + md5.length + buf.length);
        byte[] result = byteBuffer.put(lenInB).put(md5).put(buf).array();
        // 将数据发送给Client
        out.write(result);
      }
      // 关闭连接
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}
